package com.rockcent.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rockcent.common.domain.enumclass.Whether;
import com.rockcent.helper.AuthResourceHelper;
import com.rockcent.mall.lib.domain.*;
import com.rockcent.mall.lib.domain.enumclass.SystemType;
import com.rockcent.mall.lib.dto.AuthResourceDto;
import com.rockcent.mall.lib.repository.*;
import com.rockcent.service.AuthUserResourceSrv;
import com.rockcent.service.UserMallSrv;
import com.rockcent.service.UserMerchantSrv;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by zhangjh on 2017/3/16.
 */
@Service
public class AuthUserResourceSrvImpl implements AuthUserResourceSrv {

    @Autowired
    private AuthUserResourceDefaultRepository authUserResourceDefaultRepository;

    @Autowired
    private AuthResourceRepository authResourceRepository;

    @Autowired
    private AuthUserResourceRepository authUserResourceRepository;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private AuthTitleResourceRepository authTitleResourceRepository;
    @Autowired
    private UserMerchantRepository userMerchantRepository;
    @Autowired
    private UserMallRepository userMallRepository;
    @Autowired
    private UserMallSrv userMallSrv;
    @Autowired
    private UserMerchantSrv userMerchantSrv;

    /**
     * @param authTitleResourceList
     * @param userId
     * @param adminId
     */
    @Override
    public void batchSave(List<AuthTitleResource> authTitleResourceList, Long userId, Long adminId) {
        // 保存用户权限
        if (authTitleResourceList != null && authTitleResourceList.size() > 0) {
            for (AuthTitleResource authTitleResource : authTitleResourceList) {
                AuthUserResource authUserResource = new AuthUserResource();
                authUserResource.setUserId(userId);
                authUserResource.setResourceId(authTitleResource.getResourceId());
                authUserResource.setResourceParentId(authTitleResource.getResourceParentId());
                authUserResource.setUserAdminId(adminId);
                authUserResourceRepository.save(authUserResource);
            }
        }
    }


    /**
     * 添加默认菜单权限
     *
     * @param resourceIdList 菜单ID集合
     * @param systemType     系统类型
     */
    public void saveAuthUserResourceDefault(List<Long> resourceIdList, SystemType systemType) {
        if (resourceIdList != null && resourceIdList.size() > 0) {
            for (Long resourceId : resourceIdList) {
                AuthUserResourceDefault resourceDefault = new AuthUserResourceDefault();
                AuthResource authResource = authResourceRepository.findOne(resourceId);
                if (authResource != null && authResource.getParentId() != null) {
                    resourceDefault.setResourceParentId(authResource.getParentId());
                }
                resourceDefault.setResourceId(resourceId);
                resourceDefault.setSystemType(systemType);
                authUserResourceDefaultRepository.save(resourceDefault);
            }
        }
    }

    /**
     * 添加M、B端子账号权限
     *
     * @param authTitleResourceList 职称权限
     * @param userId                用户ID
     * @param mallId                平台ID
     * @param merchantId            商家ID
     */
    public void saveAuthUserResource(List<AuthTitleResource> authTitleResourceList, Long userId, Long mallId, Long merchantId) {
        if (authTitleResourceList != null && authTitleResourceList.size() > 0) {
            for (AuthTitleResource authTitleResource : authTitleResourceList) {
                AuthUserResource authUserResource = new AuthUserResource();
                authUserResource.setResourceId(authTitleResource.getResourceId());
                authUserResource.setUserId(userId);
                authUserResource.setResourceParentId(authTitleResource.getResourceParentId());
                authUserResource.setMallId(mallId);
                if (merchantId != null) {
                    authUserResource.setMerchantId(merchantId);
                }
                authUserResourceRepository.save(authUserResource);
            }
        }
    }

    /**
     * 更新子账号权限
     *
     * @param resourceIdList 菜单ID集合
     * @param mallId         平台ID
     * @param userId         用户ID
     * @param merchantId     商家ID
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void updateAuthUserResource(List<Long> resourceIdList, Long userId, Long mallId, Long merchantId) {
        if (resourceIdList != null && resourceIdList.size() > 0) {
            for (Long resourceId : resourceIdList) {
                AuthUserResource authUserResource = new AuthUserResource();
                authUserResource.setUserId(userId);
                authUserResource.setResourceId(resourceId);
                AuthResource authResource = authResourceRepository.findOne(resourceId);
                if (authResource != null && authResource.getParentId() != null) {
                    authUserResource.setResourceParentId(authResource.getParentId());
                }
                authUserResource.setMallId(mallId);
                String systemType = "MALL";
                if (merchantId != null) {
                    systemType = "MERCHANT";
                    authUserResource.setMerchantId(merchantId);
                }
                authUserResourceRepository.save(authUserResource);
                List<AuthResourceDto> authResourceList = authResourceRepository.findAuthResourceDtoList(resourceIdList, systemType);
                List<AuthResourceDto> topList = AuthResourceHelper.SINGLETON.createTree(null, authResourceList);
                AuthResourceHelper.SINGLETON.isHaveThreeLevelNode(topList);
            }
        }
    }

    private void updateUserResource(List<Long> resourceIdList, Long userId, Long mallId, Long merchantId) {
        if (resourceIdList != null) {
            for (Long resourceId : resourceIdList) {
                AuthUserResource authUserResource = new AuthUserResource();
                authUserResource.setUserId(userId);
                authUserResource.setResourceId(resourceId);
                authUserResource.setMallId(mallId);
                if (merchantId != null) {
                    authUserResource.setMerchantId(merchantId);
                }
                AuthResource authResource = authResourceRepository.findOne(resourceId);
                if (authResource != null && authResource.getParentId() != null) {
                    authUserResource.setResourceParentId(authResource.getParentId());
                }
            }
        }

    }

    /**
     * 更新M端子账号权限
     *
     * @param resourceIdList 菜单ID集合
     * @param mallId         平台ID
     * @param userId         用户ID
     * @param merchantId     商家ID
     */
    public void updateAuthUserResourceWhenAddAuthResource(List<Long> resourceIdList, Long userId, Long mallId, Long merchantId) {
        updateUserResource(resourceIdList, userId, mallId, merchantId);
    }

    @Override
    public List<AuthResourceDto> authUserResourceTree(List<AuthResourceDto> authResourceList, List<AuthUserResource> authUserResourceList) throws IOException {
        List<AuthResourceDto> authResourceDtoList = new ArrayList<>();
        if (authResourceList != null && authResourceList.size() > 0 && authUserResourceList != null && authUserResourceList.size() > 0) {
            //M、B拥有的菜单ID集合
            List<Long> resourceIdList = authUserResourceList.stream().map(AuthUserResource::getResourceId).collect(Collectors.toList());

            //收集M、B所拥有的菜单
            authResourceDtoList.addAll(authResourceList.stream().filter(resourceDto -> resourceIdList.contains(resourceDto.getId())).collect(Collectors.toList()));

            for (AuthResourceDto resourceDto : authResourceDtoList) {
                if (StringUtils.isNotBlank(resourceDto.getBackendUrl())) {
                    resourceDto.setBackendUrlList(objectMapper.readValue(resourceDto.getBackendUrl(), new TypeReference<List<String>>() {
                    }));
                } else {
                    resourceDto.setBackendUrlList(new ArrayList<>());
                }
            }
            //树形数据结构组装
            authResourceDtoList = AuthResourceHelper.SINGLETON.createTree(null, authResourceDtoList);
        }
        return authResourceDtoList;
    }

    /**
     * 保存用户角色资源
     *
     * @param titleId
     * @param userId
     * @param mallId
     * @param merchantId
     * @param systemType
     */
    @Override
    public void saveAuthTitleResourceAndAuthUserResource(Long titleId, Long userId, Long mallId, Long merchantId, SystemType systemType) {
        if (userId == null || mallId == null || titleId == null) {
            return;
        }
        if (systemType != null && systemType == SystemType.MALL) {
            List<AuthUserResource> authUserResourceList = authUserResourceRepository.findAuthUserResourceByMallIdAndUserId(mallId, userId);
            authUserResourceRepository.delete(authUserResourceList);
        }
        if (systemType != null && systemType == SystemType.MERCHANT) {
            if (merchantId == null) {
                return;
            }
            List<AuthUserResource> authUserResourceList = authUserResourceRepository.findByMallIdAndUserIdAndMerchantId(mallId, userId, merchantId);
            authUserResourceRepository.delete(authUserResourceList);
        }
        List<AuthTitleResource> authTitleResourceList = authTitleResourceRepository.findByTitleId(titleId);
        if (authTitleResourceList != null && authTitleResourceList.size() > 0) {
            for (AuthTitleResource authTitleResource : authTitleResourceList) {
                AuthUserResource authUserResource = new AuthUserResource();
                authUserResource.setResourceId(authTitleResource.getResourceId());
                authUserResource.setUserId(userId);
                authUserResource.setResourceParentId(authTitleResource.getResourceParentId());
                authUserResource.setMallId(mallId);
                authUserResource.setMerchantId(merchantId);
                authUserResourceRepository.save(authUserResource);
            }
        }
    }

    /**
     * 通过角色ID删除用户资源
     *
     * @param titleId
     * @param systemType
     */
    @Override
    public void deleteAuthUserResourceByTitleId(Long titleId, SystemType systemType) {
        if (titleId != null) {
            List<AuthTitleResource> authTitleResourceList = authTitleResourceRepository.findByTitleId(titleId);
            for (AuthTitleResource authTitleResource : authTitleResourceList) {
                List<AuthUserResource> authUserResourceList = authUserResourceRepository.findByResourceIdAndIsDelete(authTitleResource.getResourceId(), Whether.NO);
                authUserResourceRepository.delete(authUserResourceList);
                authTitleResourceRepository.delete(authTitleResource.getId());
            }
        }
    }

    /**
     * 通过角色ID更新用户资源
     *
     * @param titleId
     * @param systemType
     */
    @Override
    public void updateAuthUserResourceByTitleId(Long titleId, SystemType systemType) {
        if (titleId != null) {
            List<AuthTitleResource> authTitleResourceList = authTitleResourceRepository.findByTitleId(titleId);
            if (systemType != null && systemType == SystemType.MERCHANT) {
                List<UserMerchant> userMerchantList = userMerchantRepository.findByTitleId(titleId);
                if (userMerchantList != null && userMerchantList.size() > 0) {
                    for (UserMerchant userMerchant : userMerchantList) {
                        saveAuthUserResource(authTitleResourceList, userMerchant.getUserId(), userMerchant.getMallId(), userMerchant.getMerchantId());
                    }
                }
            } else if (systemType != null && systemType == SystemType.MALL) {
                List<UserMall> userMallList = userMallRepository.findByTitleId(titleId);
                if (userMallList != null && userMallList.size() > 0) {
                    for (UserMall userMall : userMallList) {
                        saveAuthUserResource(authTitleResourceList, userMall.getUserId(), userMall.getMallId(), null);
                    }
                }
            }
        }
    }

    /**
     * @param backUrl     后端URL
     * @param frontendUrl 前端URL
     * @return
     */
    @Override
    public List<AuthUserResource> findAuthUserResourceByUrl(String backUrl, String frontendUrl) {
        return authUserResourceRepository.findAuthUserResourceByUrl(backUrl, frontendUrl);
    }

    @Override
    public List<Long> findAuthUserIdByUrl(String backUrl, String frontendUrl) {
        return authUserResourceRepository.findAuthUserIdByUrl(backUrl, frontendUrl);
    }




    @Override
    public List<Long> findAuthUserIdByMalMerchantIdAndIsSuperAdmin(Long mallId, Long merchantId,Whether isSuperAdmin) {
        List<Long> userIds = new ArrayList<>();

        if (null != mallId) {
            List<Long> userIdsOfMall = userMallSrv.findUserIdByMallIdAndIsSuperAdmin(mallId,isSuperAdmin);
            if (null != userIdsOfMall) {
                userIds.addAll(userIdsOfMall);
            }

        }
        if (null != merchantId) {
            List<Long> userIdsOfMerchant = userMerchantSrv.findUserIdByMerchantIdAndIsSuperAdmin(merchantId,isSuperAdmin);
            if (null != userIdsOfMerchant) {
                userIds.addAll(userIdsOfMerchant);
            }
        }
        return userIds;
    }

}
